/**
 *
 */
package com.example.cxx.myapplication;

import android.animation.Animator.AnimatorListener;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.LinearInterpolator;

/**
 * The Class CircularProgressBar. 矩形进度条
 *
 * @author Guanyu.Guo
 * @version 1.0 (09.13.2014)
 * @since 09.13.2014
 */
public class RectProgressBar extends View {

    /**
     * The Constant TAG.
     */
    private static final String TAG = RectProgressBar.class.getSimpleName();

    /**
     * the width of this progress bar
     */
    private int width;

    /**
     * the height of this progress bar
     */
    private int height;

    /**
     * The rectangle which draw.
     */
    private final RectF mRectBounds = new RectF();

    /**
     * the color of the progress.
     */
    private int mProgressColor;

    /**
     * paint for the progress.
     */
    private Paint mProgressColorPaint;

    /**
     * The color of the progress background.
     */
    private int mProgressBackgroundColor;

    /**
     * the paint for the background.
     */
    private Paint mBackgroundColorPaint = new Paint();

    /**
     * the paint direction of rect progress
     */
    private boolean isHorizontal = true;

    /**
     * The current progress.
     */
    private float mProgress = 0.3f;

    /**
     * Instantiates a new holo circular progress bar.
     *
     * @param context the context
     */
    public RectProgressBar(final Context context) {
        this(context, null);
    }

    /**
     * Instantiates a new holo circular progress bar.
     *
     * @param context the context
     * @param attrs   the attrs
     */
    public RectProgressBar(final Context context,
                           final AttributeSet attrs) {
        this(context, attrs, R.attr.rectProgressBarStyle);
    }

    /**
     * Instantiates a new holo circular progress bar.
     *
     * @param context  the context
     * @param attrs    the attrs
     * @param defStyle the def style
     */
    public RectProgressBar(final Context context,
                           final AttributeSet attrs, final int defStyle) {
        super(context, attrs, defStyle);

        // load the styled attributes and set their properties
        final TypedArray attributes = context.obtainStyledAttributes(attrs,
                R.styleable.RectProgressBar, defStyle, 0);

        setProgressColor(attributes.getColor(
                R.styleable.RectProgressBar_rect_progress_color, Color.CYAN));
        setBackgroundProgressColor(attributes.getColor(
                R.styleable.RectProgressBar_rect_progress_background_color, Color.BLACK));
        setProgress(attributes.getFloat(
                R.styleable.RectProgressBar_rect_progress, 0.0f));
        attributes.recycle();

    }

    /**
     * Gets the current rotation.
     *
     * @return the current rotation
     */
    public float getCurrentRotation() {
        if (isHorizontal) {
            return width * mProgress;
        } else {
            return height * (1 - mProgress);
        }
    }

    /**
     * gives the current progress of the ProgressBar. Value between 0..1 if you
     * set the progress to >1 you'll get progress % 1 as return value
     *
     * @return the progress
     */
    public float getProgress() {
        return mProgress;
    }

    /**
     * Gets the progress color.
     *
     * @return the progress color
     */
    public int getProgressColor() {
        return mProgressColor;
    }

    /*
     * (non-Javadoc)
     *
     * @see android.view.View#onDraw(android.graphics.Canvas)
     */
    @Override
    protected void onDraw(final Canvas canvas) {

        // All of our positions are using our internal coordinate system.
        // Instead of translating
        // them we let Canvas do the work for us.
        canvas.translate(0, 0);

        final float progressRotation = getCurrentRotation();
        if (isHorizontal) {
            mRectBounds.set(0, 0, progressRotation, height);
            canvas.drawRoundRect(mRectBounds, 10, 10, mProgressColorPaint);
//			mRectBounds.set(progressRotation, 0, width, height);
//			canvas.drawRect(mRectBounds, mBackgroundColorPaint);
        } else {
            mRectBounds.set(0, progressRotation, width, height);
            canvas.drawRoundRect(mRectBounds, 10, 10, mProgressColorPaint);
//			mRectBounds.set(0, 0, width, progressRotation);
//			canvas.drawRect(mRectBounds, mBackgroundColorPaint);
        }
//		Log.e(TAG,"progressRotation: "+progressRotation);
//		Log.e(TAG,"ondraw");
    }

    /*
     * (non-Javadoc)
     *
     * @see android.view.View#onMeasure(int, int)
     */
    @Override
    protected void onMeasure(final int widthMeasureSpec,
                             final int heightMeasureSpec) {
        height = getDefaultSize(getSuggestedMinimumHeight(),
                heightMeasureSpec);
        width = getDefaultSize(getSuggestedMinimumWidth(),
                widthMeasureSpec);
        setMeasuredDimension(width, height);
    }

    /**
     * Sets the progress.
     *
     * @param progress the new progress
     */
    public void setProgress(final float progress) {
        if (progress == mProgress) {
            return;
        }

        if (progress == 1) {
            mProgress = 1;
        } else if (progress >= 1) {

            mProgress = 1;
        } else {
            mProgress = progress;
        }
        invalidate();
    }

    /**
     * Get the draw direction.
     *
     * @param
     */
    public boolean isHorizontal() {
        return isHorizontal;
    }

    /**
     * Sets the draw direction.
     *
     * @param isHorizontal draw horizontal or not
     */
    public void setHorizontal(boolean isHorizontal) {
        this.isHorizontal = isHorizontal;
    }

    /**
     * Sets the progress color.
     *
     * @param color the new progress color
     */
    public void setProgressColor(final int color) {
        mProgressColor = color;
        updateProgressColor();
    }

    /**
     * Sets the background color.
     *
     * @param color the new progress color
     */
    public void setBackgroundProgressColor(final int color) {
        mProgressBackgroundColor = color;
        updateBackgroundColor();
    }

    /**
     * updates the paint of the progress and the thumb to give them a new visual
     * style
     */
    private void updateProgressColor() {
        mProgressColorPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mProgressColorPaint.setColor(mProgressColor);
        mProgressColorPaint.setStyle(Paint.Style.FILL_AND_STROKE);
    }

    /**
     * updates the paint of the background
     */
    private void updateBackgroundColor() {
        mBackgroundColorPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mBackgroundColorPaint.setColor(mProgressBackgroundColor);
        mBackgroundColorPaint.setStyle(Paint.Style.FILL_AND_STROKE);
    }

    /**
     * animate the progress of the progressBar
     *
     * @param progressBar, which progress bar will animate
     * @param listener,    add the animator listener to this animation
     * @param progress,    end progress, the progress will from 0f to progress
     * @param duration,    the duration time of animation
     */
    @SuppressLint("NewApi")
    public void animate(final RectProgressBar progressBar, final AnimatorListener listener,
                        final float progress, final int duration) {
        animate(progressBar, listener, null, progress, duration);
    }

    /**
     * animate the progress of the progressBar
     *
     * @param progressBar,    which progress bar will animate
     * @param listener,       add the animator listener to this animation
     * @param updateListener, add the updateListener to this animation
     * @param progress,       end progress, the progress will from 0f to progress
     * @param duration,       the duration time of animation
     */
    @SuppressLint("NewApi")
    public void animate(final RectProgressBar progressBar, final AnimatorListener listener, final AnimatorUpdateListener updateListener,
                        final float progress, final int duration) {
        animate(progressBar, listener, updateListener, 0f, progress, duration);
    }

    /**
     * animate the progress of the progressBar
     *
     * @param progressBar,   which progress bar will animate
     * @param listener,      add the animator listener to this animation
     * @param startProgress, startProgress, the progress will from startProgress to endProgress
     * @param endProgress,   endProgress, the progress will from startProgress to endProgress
     * @param duration,      the duration time of animation
     */
    @SuppressLint("NewApi")
    public void animate(final RectProgressBar progressBar, final AnimatorListener listener,
                        final float startProgress, final float endProgress, final int duration) {
        animate(progressBar, listener, null, startProgress, endProgress, duration);
    }

    /**
     * animate the progress of the progressBar
     *
     * @param progressBar,    which progress bar will animate
     * @param listener,       add the animator listener to this animation
     * @param updateListener, add the updateListener to this animation
     * @param startProgress,  startProgress, the progress will from startProgress to endProgress
     * @param endProgress,    endProgress, the progress will from startProgress to endProgress
     * @param duration,       the duration time of animation
     */
    @SuppressLint("NewApi")
    public void animate(final RectProgressBar progressBar, final AnimatorListener listener, final AnimatorUpdateListener updateListener,
                        final float startProgress, final float endProgress, final int duration) {

        ObjectAnimator mProgressBarAnimator = ObjectAnimator.ofFloat(progressBar, "progress", startProgress, endProgress);
        mProgressBarAnimator.setInterpolator(new LinearInterpolator());
        mProgressBarAnimator.setDuration(duration);
        if (listener != null) {
            mProgressBarAnimator.addListener(listener);
        }
        if (updateListener != null) {
            mProgressBarAnimator.addUpdateListener(updateListener);
        }
        mProgressBarAnimator.addUpdateListener(new AnimatorUpdateListener() {

            @Override
            public void onAnimationUpdate(final ValueAnimator animation) {
                progressBar.setProgress((Float) animation.getAnimatedValue());
            }
        });
        mProgressBarAnimator.start();
    }

}
